﻿using System;
using System.Collections.Generic;
using MessageSystem.Managed.Infrastructure;

namespace MessageSystem.Managed.Rpc
{
    public class RpcService
    {
        private Int16                               _serviceId;
        private RpcDomain                           _domain;
        private RpcInvoker                          _invoker;
        private Dictionary<int, RpcSessionService>  _allSession;

        public RpcService(Int16 serviceId, RpcDomain domain)
        {
            _serviceId = serviceId;
            _domain = domain;
            _invoker = RpcFactory.Get(_serviceId);
            _allSession = new Dictionary<int, RpcSessionService>(new Int32EqualityComparer()); 
        }

        public RpcSessionService Bind(int sessionid, object impl, Action OnLost)
        {
            RpcSessionService session = new RpcSessionService(this,impl, _invoker, sessionid, OnLost, _domain);
            _allSession[sessionid] = session;
            return session;
        }

        public void UnBind(int sessionid)
        {
            _allSession.Remove(sessionid);
        }

        public void InvokeService(UInt16 flags, Int16 methodid, Int32 sessionid,Int32 OpCode,NetStream stream)
        {
            RpcSessionService session;
            if (_allSession.TryGetValue(sessionid, out session))
            {
                session.Invoke(flags, methodid, OpCode,stream);
            }
        }

        public void InvokeProxy(UInt16 flags, Int16 methodid, Int32 sessionid,Int32 OpCode,NetStream stream)
        {
            RpcSessionService session;
            if (_allSession.TryGetValue(sessionid, out session))
            {
                session.Return(flags, methodid,OpCode,stream);
            }
        }

        public void Lost()
        {
            foreach (RpcSessionService session in _allSession.Values)
            {
                session.OnLost();
            }
            _allSession = null;
            _domain = null;
            _invoker = null;
        }
    }
}
